#ifndef DOZERG_COMMAND_BASE_H_20080103
#define DOZERG_COMMAND_BASE_H_20080103

#include <../common/constants.hpp>
#include <common/Config.h>
#include <common/DataStream.h>

//Interface for Cmd class
struct ICommand
{
    virtual std::string ToStringHelp() const = 0;
    virtual bool DecodeParam(CInDataStream & ds) = 0;
    virtual void EncodeParam(COutDataStream & ds) const = 0;
    virtual ~ICommand(){}
};

const U32 HEAD_LEN = 13; //bytes, MUST be consist with the QCmdBase definition

class RCmdBase;

//Query Cmd base
class QCmdBase : public ICommand
{
    U16 magic_;
    U8  version_;
    U16 cmdtype_;
    U32 sequence_;
    U32 length_;
    friend class RCmdBase;
public:
    static QCmdBase * CreateCommand(CInDataStream & ds);
    static void ReleaseCommand(QCmdBase * cmd);
    U32 CmdType() const{return cmdtype_;}
    U32 CmdBodyLength() const{return length_;}
    std::string ToString() const;
    //virtual functions
    std::string ToStringHelp() const;
    bool DecodeParam(CInDataStream & ds);
    void EncodeParam(COutDataStream & ds) const{}
private:
    bool Decode(CInDataStream & ds);
};

//Response Cmd base
class RCmdBase : public ICommand
{
    U8  version_;
    U16 cmdtype_;
    U32 sequence_;
public:
    explicit RCmdBase(U16 cmdtype);
    RCmdBase(U16 cmdtype,const QCmdBase & qhead);
    U32 CmdType() const{return cmdtype_;}
    void Encode(COutDataStream & ds) const;
    std::string ToString() const;
    //virtual functions
    std::string ToStringHelp() const;
    bool DecodeParam(CInDataStream & ds){return true;}
    void EncodeParam(COutDataStream & ds) const;
};


#endif
